(function (win) {
	//系统通用全局JS对象
    if(!win.COMMON){
        win.COMMON = {
            lpad:function(str,char,len){
                var result = str;
                if(str != null){
                    var olen = str.length;
                    for(var i = olen;i < len;i++){
                        result = char + result;
                    }
                }
                return result;
            },
            inputDigit:function(doms){
                if(!isEmpty(doms)){
                    var keys = $.isArray(doms) ? doms : [doms];
                    var $el = null;
                    $.each(keys,function(i,key){
                        if(typeof key == "string"){
                            $el = $("#" + key);
                        }else{
                            $el = $(key);
                        }
                        $el.off("input.sys_cmn change.sys_cmn propertychange.sys_cmn").on("input.sys_cmn change.sys_cmn propertychange.sys_cmn",function(e){
                            $ipt = $(this);
                            var curVal = $ipt.val();
                            if(!isEmpty(curVal)){
                                curVal = curVal.replace(/[^0-9]+/g,"");
                                $ipt.val(curVal);
                            }
                        });
                    });
                }
            }
        };
    }
    // table标签全局JS对象
    if (!win._tag_table) {
        win._tag_table = {
            // 解析trBody内容，将其中的表达式求值并拼合到内容中
            // 表达式语法：~{exp}
            // 转义字符：~~将被当作普通“~”文本内容
            resolveTrBody: function (trBody, value, row, index) {
                var _PRE_CHAR = "~";
                var result = "";
                if (trBody != null && trBody != "") {
                    result = "";
                    // 定义4种基本模式常量
                    var CTNT = 0; // 正常内容
                    var PER = 1; // 表达式前缀(~)
                    var EXP = 2; // 表达式
                    var mode = CTNT; // 默认模式为正常内容
                    var len = trBody.length;
                    var c = null; // 每个待解析的字符
                    var exp = ""; // 识别出的表达式
                    var append = true; // 是否需要将字符拼合到结果内容中的标志
                    for (var i = 0; i < len; i++) {
                        c = trBody.charAt(i);
                        switch (mode) {
                            case CTNT:
                                // 正常内容模式下
                                if (c == _PRE_CHAR) { // 遇到“~”则进入表达式前缀模式
                                    mode = PER;
                                    append = false;
                                } else {
                                    append = true;
                                }
                                break;
                            case PER:
                                // 表达式前缀模式下
                                if (c == "{") { // 遇到“{”则进入表达式模式
                                    mode = EXP;
                                    append = false;
                                } else { // 否则进入正常内容模式
                                    mode = CTNT;
                                    append = true;
                                    if (c != _PRE_CHAR) { // 若遇到的不是“~”则说明不是~~转义，将把上一次解析的“~”作为正常文本拼合到结果中
                                        result += _PRE_CHAR;
                                    }
                                }
                                break;
                            case EXP:
                                // 表达式模式下
                                append = false;
                                if (c == "}") { // 若遇到“}”则结束表达式模式进入正常内容模式
                                    mode = CTNT;
                                    var expVal = eval("(" + exp + ")"); // 求取表达式的值
                                    if (expVal != null) {
                                        result += expVal; // 当表达式值不为空时将其拼合到结果中
                                    }
                                    exp = "";
                                } else {
                                    exp += c;
                                }
                                break;
                            default:
                                break;
                        }
                        if (append) {
                            result += c;
                        }
                    }
                }
                return result;
            },
            parseTrValueForSelect: function (value, listMap) {
                for (var o in listMap) {
                    if (listMap[o].id == value) {
                        return listMap[o].text;
                    }
                }
                return value;
            },
            formatDatetimeStr: function(str,srcPattern,destPattern){
                var result = str;
                if(result != null){
                    var DT_FIXLEN_UNITS = ["yyyy","MM","dd","HH","mm","ss"];
                    var DT_VARLEN_UNITS = ["y","M","d","H","m","s"];
                    var DT_REGEX_ESCSTR = "\\.^$*+?|()[]{}";
                    var DT_REGEX = new RegExp(DT_FIXLEN_UNITS.join("|") + "|.","g");
                    var srcMatches = srcPattern.match(DT_REGEX);
                    var srcUnits = [];
                    var srcRegex = "";
                    $.each(srcMatches,function(i,match){
                        if(DT_FIXLEN_UNITS.indexOf(match) >= 0){
                            srcUnits.push(match);
                            srcRegex += "(\\d{" + match.length + "})";
                        }else if(DT_VARLEN_UNITS.indexOf(match) >= 0){
                            srcUnits.push(match);
                            srcRegex += "(\\d{1," + ("y" == match ? "4" : "2") + "})";
                        }else{
                            srcRegex += DT_REGEX_ESCSTR.indexOf(match) >= 0 ? "\\" + match : match;
                        }
                    });
                    var elmts = result.match(srcRegex);
                    if(elmts != null){
                        var year = 1;
                        var month = 0;
                        var date = 1;
                        var hours = 0;
                        var minutes = 0;
                        var seconds = 0;
                        var i=1;
                        var len=elmts.length;
                        for(;i<len;i++){
                            var elmt = elmts[i];
                            var unit = srcUnits[i - 1];
                            switch(unit){
                            case "yyyy":
                            case "y":
                                year = parseInt(elmt);
                                break;
                            case "MM":
                            case "M":
                                month = parseInt(elmt) - 1;
                                break;
                            case "dd":
                            case "d":
                                date = parseInt(elmt);
                                break;
                            case "HH":
                            case "H":
                                hours = parseInt(elmt);
                                break;
                            case "mm":
                            case "m":
                                minutes = parseInt(elmt);
                                break;
                            case "ss":
                            case "s":
                                seconds = parseInt(elmt);
                                break;
                            default:
                                break;
                            }
                        }
                        var dt = new Date(year,month,date,hours,minutes,seconds,0);
                        var destMatches = destPattern.match(DT_REGEX);
                        result = "";
                        $.each(destMatches,function(i,match){
                            var val = match;
                            var padLen = 0;
                            switch(match){
                            case "yyyy":
                                padLen = 4;
                            case "y":
                                val = String(dt.getFullYear());
                                break;
                            case "MM":
                                padLen = 2;
                            case "M":
                                val = String(dt.getMonth() + 1);
                                break;
                            case "dd":
                                padLen = 2;
                            case "d":
                                val = String(dt.getDate());
                                break;
                            case "HH":
                                padLen = 2;
                            case "H":
                                val = String(dt.getHours());
                                break;
                            case "mm":
                                padLen = 2;
                            case "m":
                                val = String(dt.getMinutes());
                                break;
                            case "ss":
                                padLen = 2;
                            case "s":
                                val = String(dt.getSeconds());
                                break;
                            default:
                                break;
                            }
                            result += COMMON.lpad(val,"0",padLen);
                        });
                    }
                }
                return result;
            }
        };
    }
    //通用Tree弹出窗全局JS对象
    if (!win.CommonTreePopup) {
        var disCheckNonLeaf = function (zNodes) {
            var nodes = $.isArray(zNodes) ? zNodes : [zNodes];
            $.each(nodes, function (i, node) {
                var subNodes = node.children;
                if (subNodes != null && subNodes.length > 0) {
                    node.chkDisabled = true;
                    disCheckNonLeaf(subNodes);
                }
            });
        }
        win.CommonTreePopup = {
            show: function (id, options) {
                var idSel = "#" + id;
                //获取标签属性指定的初始化参数
                var init_title = $(idSel + "_opt_title").val();
                var init_treeDataStr = $(idSel + "_opt_treeData").val();
                var init_treeData = isEmpty(init_treeDataStr) ? null : eval("(" + init_treeDataStr + ")");
                var init_treeSettingStr = $(idSel + "_opt_treeSetting").val();
                var init_treeSetting = isEmpty(init_treeSettingStr) ? {} : eval("(" + init_treeSettingStr + ")");
                var init_callbackStr = $(idSel + "_opt_callback").val();
                var init_callback = isEmpty(init_callbackStr) ? null : eval("(" + init_callbackStr + ")");
                var init_multiple = $(idSel + "_opt_multiple").val();
                var init_showRoot = $(idSel + "_opt_showRoot").val();
                var init_rootName = $(idSel + "_opt_rootName").val();
                var init_rootIdKey = $(idSel + "_opt_rootIdKey").val();
                var init_rootIdValue = $(idSel + "_opt_rootIdValue").val();
                var init_onlyCheckLeaf = $(idSel + "_opt_onlyCheckLeaf").val();
                var init_parentSubRelated = $(idSel + "_opt_parentSubRelated").val();
                var init_backdrop = $(idSel + "_opt_backdrop").val();
                var init_width = $(idSel + "_opt_width").val();
                var init_height = $(idSel + "_opt_height").val();
                var init_confirmBtnText = $(idSel + "_opt_confirmBtnText").val();
                var init_cancelBtnText = $(idSel + "_opt_cancelBtnText").val();
                //默认zTree配置数据
                var treeSetting = {
                    check: {
                        enable: true,
                        chkStyle: (init_multiple == "true" ? "checkbox" : "radio"),
                        radioType: "all"
                    },
                    data: {
                        simpleData: {
                            enable: true,
                            idKey: "id",
                            pIdKey: "parent_id",
                            rootPId: 0
                        }
                    }
                };
                if(init_parentSubRelated != "true"){
                    treeSetting.check.chkboxType = {"Y":"","N":""};
                }
                //将初始化参数中的zTree配置数据合并到默认zTree配置数据
                $.extend(treeSetting, init_treeSetting);
                //构造初始化参数对象
                var opt = {
                    title: init_title,
                    treeData: init_treeData,
                    treeSetting: treeSetting,
                    callback: init_callback,
                    multiple: init_multiple,
                    showRoot: init_showRoot,
                    rootName: init_rootName,
                    rootIdKey: init_rootIdKey,
                    rootIdValue: init_rootIdValue,
                    onlyCheckLeaf: init_onlyCheckLeaf,
                    backdrop: init_backdrop,
                    width: init_width,
                    height: init_height,
                    confirmBtnText: init_confirmBtnText,
                    cancelBtnText: init_cancelBtnText
                };
                //若指定有自定义参数，且指定了multiple属性，则根据multiple参数设定zTree配置数据
                if (options != null && options.hasOwnProperty("multiple")) {
                    if (options.multiple == "true") {
                        opt.treeSetting.check.chkStyle = "checkbox";
                    } else {
                        opt.treeSetting.check.chkStyle = "radio";
                    }
                }
                //将自定义参数合并到初始化参数中
                $.extend(opt, options);
                //以上步骤实现了参数优先级控制：自定义参数会覆盖标签属性参数，参数中的zTree配置数据会覆盖multiple属性
                if (opt.title) {
                    $(idSel + "Label").text(opt.title);
                }
                if (opt.backdrop == "true") {
                    $(idSel).removeAttr("data-backdrop");
                } else {
                    $(idSel).attr("data-backdrop", "static");
                }
                if (opt.width) {
                    $(idSel + "_dialog").css("width", opt.width);
                }
                if (opt.height) {
                    $(idSel + "_dialog").css("height", opt.height);
                }
                if (opt.confirmBtnText) {
                    $(idSel + "_save").text(opt.confirmBtnText);
                }
                if (opt.cancelBtnText) {
                    $(idSel + "_close").text(opt.cancelBtnText);
                }
                $(idSel + "_save").off("click.commonTreePopup").on("click.commonTreePopup", function (e) {
                    $(idSel).modal("hide");
                    if (opt.callback) {
                        var ztree = $.fn.zTree.getZTreeObj(id + "_tree");
                        var data = ztree.getCheckedNodes(true);
                        opt.callback(data);
                    }
                });
                var zNodes;
                if (opt.showRoot == "true") {
                    var rootNode = {
                        name: opt.rootName,
                        children: opt.treeData,
                        open: true
                    };
                    rootNode[opt.rootIdKey] = opt.rootIdValue;
                    zNodes = [rootNode];
                } else {
                    zNodes = opt.treeData;
                }
                if (opt.onlyCheckLeaf == "true") {
                    disCheckNonLeaf(zNodes);
                }
                $.fn.zTree.init($(idSel + "_tree"), opt.treeSetting, zNodes);
                $(idSel).modal("show");
            },
            hide: function (id) {
                $("#" + id).modal("hide");
            }
        };
    }
    /**
     * tabs选项卡操作
     */
    if (!win._tabs) {
        win._tabs = {
            /**
             * @param tabId tab页ID，必填
             * @param url 跳转tab页对应url，不指定则默认读取tab页上配置的URL
             * @param params 跳转时传递的参数
             * @param callback 跳转后的回调方法
             * @param isControl 是否控制工具栏按钮
             * @param isParent 如果一个页面里面有嵌套，这个值必须是false
             */
            showPage: function (tabId, url, params, callback, isControl,isParent) {
                $('a[href="#' + tabId + '"]').tab("show"); //显示点击的tab页面
                var tab = $("#" + tabId);
                if (isEmpty(url)) {
                    url = tab.attr("defaultUrl");
                }
                if (isControl || (typeof isControl == "undefined" || isControl == null)) {
                    $("._common_head_bar_css button").hide();
                }
                // 请空所有tabs值
                if((typeof isParent == "undefined" || isParent == null) || isParent){
                    $('div[class="tab-content"]>div[id]').html("");
                }
                //加入时间戳
                if(!isEmpty(url)){
                    if(url.indexOf("?")>0){
                        url=url+"&time="+new Date().getTime();
                    }else{
                        url=url+"?time="+new Date().getTime();
                    }
                }

                var loadimg = ""; //Loading图片
                tab.html("<br/>" + loadimg + "正在加载中"); //设置页面加载时的loading内容
                tab.load(url, params, function () {
                    if (!isEmpty(callback)) {
                        callback();
                    }
                }); //ajax加载页面
            },
            showTab: function (tabIds, show) {
                var finalTabIds = $.isArray(tabIds) ? tabIds : [tabIds];
                $.each(finalTabIds, function (i, tabId) {
                    if (show != false) {
                        $('a[href="#' + tabId + '"]').parent().show();
                    } else {
                        $('a[href="#' + tabId + '"]').parent().hide();
                    }
                });
            }
        }
    }
    if (!win.CommonPopup) {
    	var encodeUnicodeHex = function (str) {
            var result = null;
            if (str != null) {
                result = "";
                var len = str.length;
                for (var i = 0; i < len; i++) {
                    var charCodeStr = COMMON.lpad(str.charCodeAt(i).toString(16), "0", 4);
                    result += charCodeStr;
                }
            }
            return result;
        };
        var fillParamToDummyForm = function(params,keysToBeFilled,$dummyForm){
            $.each(keysToBeFilled,function(i,key){
                var ipt = $('<input type="hidden" name="' + key + '"/>');
                ipt.val(params[key]);
                $dummyForm.append(ipt);
            });
        };
        win.CommonPopup = {
                show: function (id, customOpt) {
                    // customOpt参数列表：
                    // title - 弹出窗标题
                    // sqlKey - 通用查询sql索引key值
                    // callback - 确定选择回调js方法，接收一个data参数，为选中的行数据JSON数组
                    // filter - 通用查询过滤条件，为json键值对格式({key:value})
                    // multiple - 查询结果是否多选(true|false)
                    // backdrop - 背景框点击遮罩是否关闭(true|false)
                    // width - 弹出窗内容宽度，为css style值
                    // height - 弹出窗内容高度，为css style值
                    var idSel = "#" + id;
                    var frameJq = $(idSel + "_frame");
                    frameJq.attr("src", "");
                    var $innerBody = $(frameJq.get(0).contentWindow.document.body);
                    $innerBody.empty();
                    var popPath = $(idSel + "_popPath").val();
                    var defTitle = $(idSel + "_opt_title").val();
                    var defSqlKey = $(idSel + "_opt_sqlKey").val();
                    var defCallback = eval("(" + $(idSel + "_opt_callback").val() + ")");
                    var defFilter = null;
                    var defFilterStr = $(idSel + "_opt_filter").val();
                    if (defFilterStr != null && defFilterStr != "") {
                        defFilter = eval("(" + defFilterStr + ")");
                    }
                    var defMultiple = $(idSel + "_opt_multiple").val();
                    var defBackdrop = $(idSel + "_opt_backdrop").val();
                    var defPaginate = $(idSel + "_opt_paginate").val();
                    var defWidth = $(idSel + "_opt_width").val();
                    var defHeight = $(idSel + "_opt_height").val();
                    var defSelections = $(idSel + "_selections").val();
                    var defSelectRowJson = $(idSel + "_selectRowJson").val();
                    var defShowBack = $(idSel + "_showBack").val();
                    var defAutoInit = $(idSel + "_autoInit").val();

                    var defOpt = {
                        saveId: id + "_save",
                        title: defTitle,
                        sqlKey: defSqlKey,
                        callback: defCallback,
                        filter: defFilter,
                        multiple: defMultiple,
                        backdrop: defBackdrop,
                        paginate: defPaginate,
                        width: defWidth,
                        height: defHeight,
                        selections: defSelections,
                        selectRowJson: defSelectRowJson,
                        showBack: defShowBack,
                        autoInit: defAutoInit
                    };
                    var serverParamKeys = [
                        "saveId",
                        "sqlKey",
                        "filter",
                        "multiple",
                        "paginate",
                        "height",
                        "selections",
                        "selectRowJson",
                        "autoInit"
                    ];
                    var opt = $.extend(defOpt, customOpt);
                    if(opt.showBack != "true"){
                        opt.selections = "undefined";
                        opt.selectRowJson = "undefined";
                    }else{
                        if(isEmpty(opt.selections)){
                            opt.selections = "undefined";
                        }
                        if(isEmpty(opt.selectRowJson)){
                            opt.selectRowJson = "undefined";
                        }
                    }
                    $(idSel + "_save").off("click.commonPopup").on("click.commonPopup", function () {
                        //回填参数
                        console.log(window.frames[id + "_frame"].$("#_commonPopupTable_select_ids").val())
                        if (opt.showBack == "true") {
                            if (opt.multiple == 'false') {
                                $(idSel + "_selections").val("'" + window.frames[id + "_frame"].$("#_commonPopupTable_select_ids").val() + "'");
                            }
                            //$(idSel + "_selectRowJson").val(window.frames[id + "_frame"].$("#_commonPopupTable_select_rows_json").val());
                        }
                        $(idSel).modal("hide");
                        if (opt.callback) {
                            var dataJson = window.frames[id + "_frame"].$("#_commonPopupTable_select_rows_json").val();
                            var data = isEmpty(dataJson) ? [] : JSON.parse(dataJson);
                            opt.callback(data);
                        }
                    });
                    $(idSel + "_clear").off("click").on("click", function () {
                        //清空记录的选项
                        $(idSel + "_selections").val("");
                        window.frames[id + "_frame"].$("#_commonPopupTable_select_ids").val("");
                        $(idSel + "_selectRowJson").val("");
                        window.frames[id + "_frame"].$("#_commonPopupTable_select_rows_json").val("");
                        //frameJq.attr("src", tempPath);
                        window.frames[id + "_frame"].$("#_commonPopupTable").bootstrapTable("uncheckAll");
                    });
                    if (opt.title) {
                        $(idSel + "Label").text(opt.title);
                    }
                    if (opt.backdrop == "true") {
                        $(idSel).removeAttr("data-backdrop");
                    } else {
                        $(idSel).attr("data-backdrop", "static");
                    }
                    if (opt.width) {
                        $(idSel + "_dialog").css("width", opt.width);
                    }
                    if (opt.height) {
                        frameJq.css("height", opt.height);
                    }
                    var $dummyForm = $('<form action="' + popPath + '" method="POST"></form>');
                    fillParamToDummyForm($.extend({},opt,{
                            filter:JSON.stringify(opt.filter),
                            keepParamsKeyStr:serverParamKeys.join()
                        }),serverParamKeys.concat(["keepParamsKeyStr"]),$dummyForm);
                    $dummyForm.appendTo($innerBody);
                    $dummyForm.submit();
                    $(idSel).modal("show");
                },
                hide: function (id) {
                    $("#" + id).modal("hide");
                }
            };
    }
    
    /**
     * 公共工具栏操作
     */
    if (!win._headToolBar) {
        win._headToolBar = {
            saveBtn: function (headToolbarId, tableId, onSaveEditCallBack) {
                if (isEmpty(headToolbarId)) {
                    //为空加入默认值
                    headToolbarId = "_common_head_bar";
                }
                headToolbarId = "#" + headToolbarId + "_Save";
                $(headToolbarId).show();
                $(headToolbarId).unbind();
                $(headToolbarId).click(function () {
                    if (isEmpty(tableId)) {
                        onSaveEditCallBack();
                    } else {
                        var resultData = $("#" + tableId).bootstrapTable("cer_confirmEditAllRows");
                        if (!isEmpty(onSaveEditCallBack)) {
                            onSaveEditCallBack(resultData);
                        }
                    }

                });
            },
            /**
             * 自定义按钮，调用方法
             * @param moreBtnId 自定义按钮id
             * @param callback 调用后回调方法
             */
            moreBtn: function (moreBtnId, callback) {
                $("#" + moreBtnId).show();
                $("#" + moreBtnId).unbind();
                $("#" + moreBtnId).click(function () {
                    callback();
                });
            },
            /**
             * 显示按钮
             * @param moreBtnId 自定义按钮id
             */
            showBtn: function (moreBtnId) {
                $("#" + moreBtnId).show();
                
            }

        }
    }
})(window);